package secrpc

import (
	"dub/define"
	"dub/define/grpcmodel"
	"dub/utils"
	"fmt"
	"golang.org/x/net/context"
	"regexp"
	"time"
)

type SecRpcAgent struct {
	log   *utils.Logger
	dbRpc *utils.RpcProxy
}

//修改用户信息
func (s *SecRpcAgent) Update(ctx context.Context, args *grpcmodel.ModelSecRpcAgentReqUpdate) (reply *grpcmodel.ModelSecRpcAgentResUpdate, err error) {
	reply = &grpcmodel.ModelSecRpcAgentResUpdate{}

	db_args := &grpcmodel.ModelDbRpcAgentReqUpdate{
		IsAllUpdate: args.GetIsAllUpdate(),
		ModelDbRpcAgent: &grpcmodel.ModelDbRpcAgent{
			AgentId:     args.GetModelSecRpcAgent().GetAgentId(),
			LoginName:   args.GetModelSecRpcAgent().GetLoginName(),
			RegionCode:  args.GetModelSecRpcAgent().GetRegionCode(),
			AgentStatus: args.GetModelSecRpcAgent().GetAgentStatus(),
			LoginPwd:    args.GetModelSecRpcAgent().GetLoginPwd(),
			AgentPrice:  args.GetModelSecRpcAgent().GetAgentPrice(),
		},
	}
	db_agent := grpcmodel.NewIDbRpcAgentClient(s.dbRpc.Conn())
	s.log.Infof("def_func_sec_agent.go Update method db_agent.Find db_args info is %+v\n", db_args)
	db_reply, err := db_agent.Update(s.dbRpc.Context(), db_args)
	s.log.Infof("def_func_sec_agent.go Update method db_agent.Find db_reply info is %+v\n", db_reply)
	for {
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go Update method db_agent.Find err. %v\n", err)
			reply.Err = 2
			break
		}
		if db_reply.GetErr() > 0 {
			if db_reply.GetErr() > 1 {
				s.log.Errorf("def_func_sec_agent.go Update method db_agent.Find err. %v\n", err)
			}
			reply.Err = db_reply.GetErr()
			break
		}
		reply.AgentId = db_reply.GetAgentId()
		break
	}
	return
}

func (s *SecRpcAgent) Login(ctx context.Context, args *grpcmodel.ModelSecRpcAgentReqFind) (reply *grpcmodel.ModelSecRpcAgentResLogin, err error) {
	reply = &grpcmodel.ModelSecRpcAgentResLogin{}
	for {
		if args.GetLoginName() == "" || args.GetLoginPwd() == "" {
			reply.Err = 3
			break
		}

		rp_name_arg := &grpcmodel.ModelDbRpcAgentReqFind{
			LoginName: args.GetLoginName(),
		}
		db_agent := grpcmodel.NewIDbRpcAgentClient(s.dbRpc.Conn())
		s.log.Infof("def_func_sec_agent.go Login method db_agent.FindUser rp_name_arg info is %+v\n", rp_name_arg)
		rp_name_reply, err := db_agent.FindUser(s.dbRpc.Context(), rp_name_arg)
		s.log.Infof("def_func_sec_memlabel.go Login method db_agent.FindUser rp_name_reply info is %+v\n", rp_name_reply)
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go Login method db_agent.FindUser err. %v\n", err)
			reply.Err = 2
			break
		}

		if rp_name_reply.GetErr() == 1 {
			reply.Err = 1
			break
		}
		if rp_name_reply.GetErr() > 1 {
			reply.Err = rp_name_reply.GetErr()
		}
		//判断用户名密码是否正确
		if rp_name_reply.GetModelDbRpcAgent().GetLoginName() != args.GetLoginName() || rp_name_reply.GetModelDbRpcAgent().GetLoginPwd() != args.GetLoginPwd() {
			reply.Err = 4
			break
		}
		reply_model := &grpcmodel.ModelSecRpcAgent{}
		reply_model.AgentId = rp_name_reply.GetModelDbRpcAgent().GetAgentId()
		reply_model.AgentStatus = rp_name_reply.GetModelDbRpcAgent().GetAgentStatus()
		reply_model.AgentTime = rp_name_reply.GetModelDbRpcAgent().GetAddTime()
		reply_model.AgentTimeShow = time.Unix(int64(rp_name_reply.GetModelDbRpcAgent().GetAddTime()), 0).Format("2006-01-02")
		reply_model.LoginName = rp_name_reply.GetModelDbRpcAgent().GetLoginName()
		reply_model.LoginPwd = rp_name_reply.GetModelDbRpcAgent().GetLoginPwd()
		reply_model.RegionCode = rp_name_reply.GetModelDbRpcAgent().GetRegionCode()
		reply_model.RoleId = rp_name_reply.GetModelDbRpcAgent().GetRoleId()
		reply_model.AgentEditTime = rp_name_reply.GetModelDbRpcAgent().GetEditTime()
		reply_model.AgentPrice = rp_name_reply.GetModelDbRpcAgent().GetAgentPrice()
		reply_model.StatusName = s.statusShowName(reply_model.AgentStatus)

		//把查询出来的区域信息转化为键值信息
		region_map := _secRpcRegion.regionMaps()
		//代理位置的全部信息
		if len(reply_model.RegionCode) == 6 {
			reply_model.RegionName = _secRpcRegion.allRegionName(region_map, rp_name_reply.GetModelDbRpcAgent().GetRegionCode())
		}
		reply.ModelSecRpcAgent = reply_model

		//查询代理对应的角色编号
		role_args := &grpcmodel.ModelDbRpcRoleReqFind{
			RoleId:     reply_model.GetRoleId(),
			IsJustRole: true,
		}
		db_role := grpcmodel.NewIDbRpcRoleClient(s.dbRpc.Conn())
		s.log.Infof("def_func_sec_agent.go Login method db_role.FindRole role_args info is %+v\n", role_args)
		role_reply, err := db_role.FindRole(s.dbRpc.Context(), role_args)
		s.log.Infof("def_func_sec_memlabel.go Login method db_role.FindRole role_reply info is %+v\n", role_reply)
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go Login method db_role.FindRole err. %v\n", err)
			reply.Err = 2
			break
		}
		if role_reply.GetErr() > 0 {
			reply.Err = role_reply.GetErr()
			break
		}
		reply_model.RoleName = role_reply.GetModelDbRpcRole().GetRoleName()
		reply.ModelSecRpcAgent = reply_model

		//如果是tcp协议登录就直接返回不需要查询相应的权限信息
		if args.ReqType == 3 {
			break
		}

		//固定处理代理微服务的权限信息
		auth_args := &grpcmodel.ModelDbRpcAuthReqFind{
			RoleId:      reply_model.GetRoleId(),
			MicroServer: define.ServerNameWeb_ManAgentServer,
		}
		db_auth := grpcmodel.NewIDbRpcAuthClient(s.dbRpc.Conn())
		s.log.Infof("def_func_sec_agent.go Login method db_auth.Find auth_args info is %+v\n", auth_args)
		auth_reply, err := db_auth.Find(s.dbRpc.Context(), auth_args)
		s.log.Infof("def_func_sec_agent.go Login method db_auth.Find auth_reply info is %+v\n", auth_reply)
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go Login method db_auth.Find err. %v\n", err)
			reply.Err = 2
			break
		}
		reply.Err = auth_reply.GetErr()
		if reply.GetErr() == 2 || auth_reply.GetRows() == nil || len(auth_reply.GetRows()) < 1 {
			break
		}
		if reply.GetErr() == 1 {
			break
		}

		auth_all_args := &grpcmodel.ModelDbRpcAuthReqFind{}
		s.log.Infof("def_func_sec_agent.go Login method db_auth.FindAll auth_all_args info is %+v\n", auth_all_args)
		auth_all_reply, err := db_auth.FindAll(s.dbRpc.Context(), auth_all_args)
		s.log.Infof("def_func_sec_agent.go Login method db_auth.FindAll auth_all_reply info is %+v\n", auth_all_reply)
		if err != nil {
			s.log.Errorf("def_fun_sec_use.go Login method db_auth.FindAll err. %v\n", err)
			reply.Err = 2
			break
		}
		reply.Err = auth_all_reply.GetErr()
		if reply.GetErr() == 2 || auth_all_reply.GetAuths() == nil || len(auth_all_reply.GetAuths()) < 1 {
			break
		}
		if reply.GetErr() == 1 {
			break
		}

		reply.Auths = make([]*grpcmodel.ModelSecRpcAuth, 0)
		use_entity_auth_map := make(map[uint]string)
		for _, auth := range auth_reply.GetRows() {
			if args.GetReqType() == auth.GetAuthType() {
				sec_auth := &grpcmodel.ModelSecRpcAuth{
					AuthId:              auth.GetAuthId(),
					AuthPreId:           auth.GetAuthPreId(),
					AuthName:            auth.GetAuthName(),
					AuthMicroServerName: auth.GetAuthMicroServerName(),
					AuthUrl:             auth.GetAuthUrl(),
					AuthShowStatus:      auth.GetAuthShowStatus(),
					AuthType:            auth.GetAuthType(),
				}

				for _, enauth := range auth_all_reply.GetAuths() {
					len_enauth := len(enauth.GetAuthUrl())
					if auth.GetAuthId() == enauth.GetAuthId() && len_enauth > 0 {
						use_entity_auth_map[uint(enauth.GetAuthId())] = fmt.Sprintf("[%s]%s", enauth.GetAuthMicroServerName(), enauth.GetAuthUrl())
					}

					if auth.GetAuthNeedUrls() != nil && len(auth.GetAuthNeedUrls()) > 0 {
						binary_auth := fmt.Sprintf("%b", auth.GetRoleAuthConf())
						len_binary_auth := len(binary_auth)
						for i, needId := range auth.GetAuthNeedUrls() {
							//binary_auth是数字转换的二进制字符口串，1对应的ascii是49，0是48
							if needId == enauth.GetAuthId() && len_enauth > 0 && i < len_binary_auth && binary_auth[i] == 49 {
								use_entity_auth_map[uint(enauth.GetAuthId())] = fmt.Sprintf("[%s]%s", enauth.GetAuthMicroServerName(), enauth.GetAuthUrl())
							}
						}
					}
				}

				reply.Auths = append(reply.Auths, sec_auth)
			}
		}

		//把用户的实体权限添加进去
		if len(use_entity_auth_map) > 0 {
			reply.PhyAuths = make([]string, 0, len(use_entity_auth_map))
			for _, val := range use_entity_auth_map {
				reply.PhyAuths = append(reply.PhyAuths, val)
			}
		}
		break
	}
	return
}

//状态的显示名
func (s *SecRpcAgent) statusShowName(status uint32) string {
	statsShowName := ""
	switch status {
	case 1:
		statsShowName = "启用"
	case 2:
		statsShowName = "禁用"
	default:
		statsShowName = "删除"
	}
	return statsShowName
}

//根据条件查询代理信息
func (s *SecRpcAgent) Find(ctx context.Context, args *grpcmodel.ModelSecRpcAgentReqFind) (reply *grpcmodel.ModelSecRpcAgentResFind, err error) {
	reply = &grpcmodel.ModelSecRpcAgentResFind{}
	for {
		//判断参数是否合法
		if args.GetIsPage() && args.GetPageSize() < 1 {
			reply.Err = 3
			break
		}

		agents_args := &grpcmodel.ModelDbRpcAgentReqFind{
			IsPage:   args.GetIsPage(),
			PageSize: args.GetPageSize(),
			StartRow: args.GetStartRow(),
			AddUseId: args.GetAddUseId(),
		}
		db_agent := grpcmodel.NewIDbRpcAgentClient(s.dbRpc.Conn())
		s.log.Infof("def_func_sec_agent.go Find method db_auth.Find agents_args info is %+v\n", agents_args)
		agents_reply, err := db_agent.Find(s.dbRpc.Context(), agents_args)
		s.log.Infof("def_func_sec_agent.go Find method db_auth.Find agents_reply info is %+v\n", agents_reply)
		if err != nil {
			reply.Err = 2
			s.log.Errorf("def_func_sec_agent.go Find method db_auth.Find err. %v\n", err)
			break
		}
		if agents_reply.GetErr() > 0 {
			reply.Err = agents_reply.GetErr()
			break
		}

		region_map := _secRpcRegion.regionMaps()
		//组合信息
		res_models := make([]*grpcmodel.ModelSecRpcAgent, 0, len(agents_reply.GetRows()))
		for _, agent := range agents_reply.GetRows() {
			res_model := &grpcmodel.ModelSecRpcAgent{
				AgentId:       agent.GetAgentId(),
				AddUseId:      agent.GetAddUseId(),
				AddUseName:    agent.GetAddUseName(),
				LoginName:     agent.GetLoginName(),
				RegionCode:    agent.GetRegionCode(),
				AgentTime:     agent.GetAddTime(),
				AgentPrice:    agent.GetAgentPrice(),
				AgentStatus:   agent.GetAgentStatus(),
				AgentTimeShow: time.Unix(int64(agent.GetAddTime()), 0).Format("2006-01-02"),
				StatusName:    s.statusShowName(agent.AgentStatus),
			}

			//代理位置的全部信息
			if len(agent.GetRegionCode()) == 6 {
				res_model.RegionName = _secRpcRegion.allRegionName(region_map, agent.GetRegionCode())
			}

			res_models = append(res_models, res_model)
		}

		reply.Total = agents_reply.GetTotal()
		reply.Rows = res_models
		break
	}
	return
}

//添加代理信息
// func (s *SecRpcAgent) Add(args *define.RpcSecAgentReqAddAgent, reply *define.RpcSecAgentResAddAgent) error {
func (s *SecRpcAgent) Add(ctx context.Context, args *grpcmodel.ModelSecRpcAgentReqAdd) (reply *grpcmodel.ModelSecRpcAgentResAdd, err error) {
	reply = &grpcmodel.ModelSecRpcAgentResAdd{}
	for {
		if args.GetModelSecRpcAgent().GetLoginName() == "" || args.GetModelSecRpcAgent().GetLoginPwd() == "" || args.GetModelSecRpcAgent().GetRegionCode() == "" {
			reply.Err = 3
			break
		}

		//验证行政区编号是否合法
		regionCode_vali, _ := regexp.MatchString("^[0-9]{6}", args.GetModelSecRpcAgent().GetRegionCode())
		if regionCode_vali {
			//验证是否存在行政区
			re_args := &grpcmodel.ModelDbRpcRegionReqFind{
				RegionCode: args.GetModelSecRpcAgent().GetRegionCode(),
			}
			db_region := grpcmodel.NewIDbRpcRegionClient(s.dbRpc.Conn())
			s.log.Infof("def_func_sec_agent.go Add method db_region.FindRegion re_args info is %+v\n", re_args)
			re_reply, err := db_region.FindRegion(s.dbRpc.Context(), re_args)
			s.log.Infof("def_func_sec_agent.go Add method db_region.FindRegion re_reply info is %+v\n", re_reply)
			if err != nil {
				s.log.Errorf("def_func_sec_agent.go Add method db_region.FindRegion err. %v\n", err)
				reply.Err = 2
				break
			}

			if re_reply.GetErr() > 0 {
				reply.Err = 3
				break
			}
		} else {
			reply.Err = 3
			break
		}

		//判断用户名是否重复
		rp_name_arg := &grpcmodel.ModelDbRpcAgentReqFind{
			LoginName: args.GetModelSecRpcAgent().GetLoginName(),
		}
		db_agent := grpcmodel.NewIDbRpcAgentClient(s.dbRpc.Conn())
		s.log.Infof("def_func_sec_agent.go Add method db_agent.FindUser rp_name_arg info is %+v\n", rp_name_arg)
		rp_name_reply, err := db_agent.FindUser(s.dbRpc.Context(), rp_name_arg)
		s.log.Infof("def_func_sec_agent.go Add method db_agent.FindUser rp_name_reply info is %+v\n", rp_name_reply)
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go Add method db_agent.FindUser err. %v\n", err)
			reply.Err = 2
			break
		}
		if rp_name_reply.GetErr() != 1 {
			reply.Err = 1
			break
		}

		//查询代理对应的角色编号
		role_args := &grpcmodel.ModelDbRpcRoleReqFind{
			RoleCode:   define.Role_Code_Agent,
			IsJustRole: true,
		}
		db_role := grpcmodel.NewIDbRpcRoleClient(s.dbRpc.Conn())
		s.log.Infof("def_func_sec_agent.go Add method db_role.FindRole role_args info is %+v\n", role_args)
		role_reply, err := db_role.FindRole(s.dbRpc.Context(), role_args)
		s.log.Infof("def_func_sec_agent.go Add method db_role.FindRole role_reply info is %+v\n", role_reply)
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go AddAgent method db_role.FindRole err. %v\n", err)
			reply.Err = 2
			break
		}
		if role_reply.GetErr() > 0 {
			reply.Err = role_reply.GetErr()
			break
		}
		roleId := role_reply.GetModelDbRpcRole().GetRoleId()

		//添加代理
		add_args := &grpcmodel.ModelDbRpcAgentReqAdd{
			ModelDbRpcAgent: &grpcmodel.ModelDbRpcAgent{
				RoleId:      roleId,
				AgentStatus: 1, //因为是添加默认是1
				RegionCode:  args.GetModelSecRpcAgent().GetRegionCode(),
				LoginName:   args.GetModelSecRpcAgent().GetLoginName(),
				LoginPwd:    args.GetModelSecRpcAgent().GetLoginPwd(),
				AgentPrice:  args.GetModelSecRpcAgent().GetAgentPrice(),
				AddUseId:    args.GetModelSecRpcAgent().GetAddUseId(),
			},
		}
		s.log.Infof("def_func_sec_agent.go Add method db_agent.Add add_args info is %+v\n", add_args)
		add_reply, err := db_agent.Add(s.dbRpc.Context(), add_args)
		s.log.Infof("def_func_sec_agent.go Add method db_agent.Add add_reply info is %+v\n", add_reply)
		if err != nil {
			s.log.Errorf("def_func_sec_agent.go AddAgent method s.dbRpc.Call AgentRpc.AddAgent err. %v\n", err)
			reply.Err = 2
			break
		}
		reply.Err = add_reply.GetErr()
		if add_reply.GetErr() > 1 {
			reply.Err = add_reply.GetErr()
			break
		}
		reply.AgentId = add_reply.GetAgentId()
		break
	}
	return
}

var _secRpcAgent *SecRpcAgent

func NewSecRpcAgent(log *utils.Logger, dbRpc *utils.RpcProxy) *SecRpcAgent {
	if _secRpcAgent == nil {
		_secRpcAgent = &SecRpcAgent{
			log:   log,
			dbRpc: dbRpc,
		}
	}
	return _secRpcAgent
}
